package com.xiangxiao.rpan.authority.oauth;

import com.xiangxiao.rpan.authority.constant.ResponseCode;
import com.xiangxiao.rpan.authority.constant.ResponseMessage;
import com.xiangxiao.rpan.authority.dto.JsonObject;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import java.util.Map;

/**
 * @auther xiangxiao
 * @email 573768011@qq.com
 * @data 2023/7/19 19:02
 */
@ControllerAdvice
public class Oauth2ResponseBodyAdvice implements ResponseBodyAdvice<Object> {

  @Override
  public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
    //此处返回true,表示对任何handler的responsebody都调用beforeBodyWrite方法，如果有特殊方法不使用可以考虑使用注解等方式过滤
    return true;
  }

  @Override
  public Object beforeBodyWrite(Object body, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
    System.out.println("请求返回数据类型class="+ body.getClass().getName());
    if ( body.getClass().getName().equals("com.xiangxiao.rpan.authority.dto.JsonObject")) {
      //已异常处理直接返回
      return body;
    } else if (body instanceof OAuth2Authentication){
      // access_token验证
      return new JsonObject(ResponseMessage.LOGGED_SUCCESS, ResponseCode.RESULT_SUCCESS, body);
    } else if ( body instanceof DefaultOAuth2AccessToken) {
      // 登录获取access_token、refresh_token以及部分身份信息
      return new JsonObject(ResponseMessage.LOGGED_SUCCESS, ResponseCode.RESULT_SUCCESS, body);
    }else if (body instanceof Map) {
      // 部分未捕获异常以及token获取用户信息
      return body;
    }else {
      //其他异常或未发现问题直接返回
      return body;
    }
  }
}
